package com.xc.content.service;


import com.xc.content.bo.TeachPlanBO;
import com.xc.content.constant.ExceptionCode;
import com.xc.content.convert.TeachPlanServiceConverter;
import com.xc.content.entity.TeachPlan;
import com.xc.content.enums.HttpStatus;
import com.xc.content.exception.DatabaseException;
import com.xc.content.exception.SystemException;
import com.xc.content.mapper.TeachPlanMapper;
import com.xc.content.utils.ExceptionUtil;
import com.xc.content.utils.SnowflakeUtil;
import com.xc.content.utils.TeachPlanTreeNode;
import com.xc.content.utils.TreeNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


import javax.annotation.Resource;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author: hyacinth
 * @CreateTime: 2025-01-07
 * @Version: 1.0
 */
@Service("teachPlanService")
@Slf4j
public class TeachPlanService {

    @Resource
    private TeachPlanMapper teachPlanMapper;


    /**
     * 新增课程计划接口
     *
     * @param teachPlanBOList
     * @return
     */
    @Transactional
    public Boolean addTeachPlan(List<TeachPlanBO> teachPlanBOList) {
        List<TeachPlan> teachPlans = TeachPlanServiceConverter.INSTANCE.convertBOListToEntityList(teachPlanBOList);
        int num = 0;
        // 使用 Stream 流处理
        for (TeachPlan teachPlan : teachPlans) {
            if (Objects.equals(teachPlan.getParentId(), "0")) {
                log.info("新增的这个计划是章");
                buildParams(teachPlan);
                Integer i = teachPlanMapper.selectMaxOrderByGrade(teachPlan.getGrade());
                if (Objects.equals(i, null)) {
                    teachPlan.setOrderBy(1);
                } else {
                    teachPlan.setOrderBy(i + 1);
                }
            } else {
                log.info("新增的这个计划是节");
                TeachPlan teachPlan1 = teachPlanMapper.selectById(teachPlan.getParentId());
                if (ObjectUtils.isEmpty(teachPlan1)) {
                    throw new DatabaseException(ExceptionCode.FIVE_HUNDRED_CODE, "未查询到该父节点");
                }
                Integer i = teachPlanMapper.selectMaxOrderByGradeAndParentId(teachPlan.getGrade(), teachPlan.getParentId());
                if (Objects.equals(i, null)) {
                    teachPlan.setOrderBy(1);
                } else {
                    teachPlan.setOrderBy(i + 1);
                }
                buildParams(teachPlan);
            }
            int count = teachPlanMapper.addTeachPlan(teachPlan);
            num += count;
        }
        if (num < teachPlans.size()) {
            log.error("课程计划新增失败");
            throw new DatabaseException(ExceptionCode.FIVE_HUNDRED_CODE, "课程计划新增失败");
        }
        return true;
    }

    /**
     * 修改课程计划信息接口
     *
     * @param teachPlanBO
     * @return
     */
    public Boolean updateTeachPlan(TeachPlanBO teachPlanBO) {
        if (ObjectUtils.isEmpty(teachPlanMapper.selectById(teachPlanBO.getId()))) {
            log.error("为查询到id为:" + teachPlanBO.getId() + "的课程计划！");
            throw new DatabaseException(ExceptionCode.FIVE_HUNDRED_CODE, "为查询到id为:" + teachPlanBO.getId() + "的课程计划！");
        }
        try {
            TeachPlan teachPlan = TeachPlanServiceConverter.INSTANCE.convertBOToEntity(teachPlanBO);
            teachPlan.setChangeDate(new Date());
            int update = teachPlanMapper.update(teachPlan);
            if (update <= 0) {
                throw new DatabaseException(ExceptionCode.FIVE_HUNDRED_CODE, "修改课程计划失败");
            }
            return true;
        } catch (SystemException e) {
            throw new SystemException(ExceptionCode.FIVE_HUNDRED_CODE, "接口内部异常", e);
        }


    }

    /**
     * 删除/批量删除课程计划
     *
     * @param ids
     * @return
     */
    @Transactional
    public Boolean deletedTeachPlan(List<String> ids) {
        int deletedCount = 0;
        try {
            deletedCount = teachPlanMapper.deleteBatch(ids);
            if (deletedCount != ids.size()) {
                log.error("批量删除课程计划失败,预期删除：{}，实际删除：{}", ids.size(), deletedCount);
                throw new DatabaseException(ExceptionCode.FIVE_HUNDRED_CODE, "批量删除课程计划失败");
            }
            // 统一查询所有子课程计划
            List<TeachPlan> allSubTeachPlans = teachPlanMapper.selectListByParentIds(ids);
            if (!CollectionUtils.isEmpty(allSubTeachPlans)) {
                // 收集所有子课程计划的id
                List<String> allSubIds = allSubTeachPlans.stream().map(TeachPlan::getId).collect(Collectors.toList());
                // 批量删除子课程计划
                if (!CollectionUtils.isEmpty(ids)) {
                    int deleteCount = teachPlanMapper.deleteBatch(ids);
                    if (deleteCount != ids.size()) {
                        log.error("批量删除子课程计划失败，预期删除：{}，实际删除：{}", ids.size(), deleteCount);
                        throw new DatabaseException(ExceptionCode.FIVE_HUNDRED_CODE, "批量删除子课程计划失败");
                    }
                }
            }
            return true;
        } catch (SystemException e) {
            throw new SystemException(ExceptionCode.FIVE_HUNDRED_CODE, "接口内部异常", e);
        }
    }


    /**
     * 补充id和创建时间
     *
     * @param teachPlan
     */
    private static void buildParams(TeachPlan teachPlan) {
        String id = SnowflakeUtil.nextId();
        teachPlan.setId(id);
        teachPlan.setCreateDate(new Date());
    }

    /**
     * 树状查询课程计划
     *
     * @return
     */
    public List<TeachPlanTreeNode> getTeachPlanTree() {
        List<TeachPlan> teachPlanList = teachPlanMapper.queryList();

        List<TeachPlanTreeNode> teachPlanVos = teachPlanList.stream()
                .map(teachPlan -> {
                    TeachPlanTreeNode teachPlanVo = new TeachPlanTreeNode();
                    BeanUtils.copyProperties(teachPlan, teachPlanVo);
                    return teachPlanVo;
                })
                .collect(Collectors.toList());

        List<TeachPlanTreeNode> treeNodeList = teachPlanVos.stream()
                .filter(teachPlanVo -> teachPlanVo.getParentId().equals("0"))
                .peek((menu) -> menu.setChildren(getChildrenData(menu, teachPlanVos)
                ))
                .sorted(Comparator.comparing(TeachPlanTreeNode::getOrderBy, Comparator.nullsFirst(Integer::compareTo)))
                .collect(Collectors.toList());
        return treeNodeList;
    }

    /**
     * 获取孩子（下级目录）的方法，递归实现
     *
     * @param menu         当前节点
     * @param teachPlanVos 所有节点列表
     * @return 当前节点的子节点列表
     */
    public List<TeachPlanTreeNode> getChildrenData(TeachPlanTreeNode menu, List<TeachPlanTreeNode> teachPlanVos) {
        if (menu == null) {
            return new ArrayList<>();
        }
        List<TeachPlanTreeNode> treeNodes = teachPlanVos.stream()
                .filter(teachPlanVo -> teachPlanVo.getParentId().equals(menu.getId()))
                .peek(teachPlanVo -> teachPlanVo.setChildren(getChildrenData(teachPlanVo, teachPlanVos)))
                .sorted(Comparator.comparing(TeachPlanTreeNode::getOrderBy, Comparator.nullsFirst(Integer::compareTo)))
                .collect(Collectors.toList());
        return treeNodes;
    }


}
